home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / sun4c.md / devSmem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  11.1 KB  |  364 lines

  1. /* 
  2.  * devSmem.c --
  3.  *
  4.  *    Stubs to implement /dev/smem.  Allow reading and writing
  5.  *      to kernel memory.
  6.  *
  7.  *
  8.  * Copyright 1987 Regents of the University of California
  9.  * All rights reserved.
  10.  */
  11.  
  12. #ifndef lint
  13. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/sun4c.md/devSmem.c,v 1.1 92/08/13 15:54:01 secor Exp $ SPRITE (Berkeley)";
  14. #endif not lint
  15.  
  16. #include "sprite.h"
  17. #include "fs.h"
  18. #include <vmSunConst.h>
  19. #include <dbg.h>
  20. #define NOGAP
  21.  
  22. static char smemBuf[1024];
  23. extern int vm_PageSize;
  24. extern int mach_KernStackSize;
  25. extern int vmBlockCacheEndAddr;
  26. extern int vmBlockCacheBaseAddr;
  27. extern int vmStackEndAddr;
  28. extern int vmStackBaseAddr;
  29. extern int vmMemEnd;
  30. extern Address mach_KernStart;
  31. extern Address mach_CodeStart;
  32. extern int end;
  33.  
  34.  
  35. /*
  36.  *----------------------------------------------------------------------
  37.  *
  38.  *  Dev_SmemRead --
  39.  *
  40.  *    Return number of bytes read and SUCCESS if nonzero bytes returned.
  41.  *
  42.  * Results:
  43.  *    A standard Sprite return status.
  44.  *
  45.  * Side effects:
  46.  *    None.
  47.  *
  48.  *----------------------------------------------------------------------
  49.  */
  50. /*ARGSUSED*/
  51. ReturnStatus
  52. Dev_SmemRead(devicePtr, readPtr, replyPtr)
  53.     Fs_Device *devicePtr;
  54.     Fs_IOParam    *readPtr;    /* Read parameter block */
  55.     Fs_IOReply    *replyPtr;    /* Return length and signal */ 
  56. {
  57.   int status, bytesLeft;
  58.   int kernelAddress;
  59.   int numPages, bytesInPage;
  60.   char *bufPtr;
  61.   StopInfo stopInfo;
  62.   Dbg_DumpBounds currentBounds;
  63.   
  64.   stopInfo.codeStart = (int)mach_CodeStart;
  65.   stopInfo.trapType = 0;
  66. /*  stopInfo.regs = ;*/
  67.   currentBounds.pageSize = vm_PageSize;
  68.   currentBounds.stackSize = mach_KernStackSize;
  69.   currentBounds.kernelCodeStart = (unsigned int) mach_KernStart;
  70.   currentBounds.kernelCodeSize  =
  71.     (unsigned int) (((Address)(&end)) - mach_KernStart);
  72.   currentBounds.kernelDataStart  = ((unsigned int)(&end));
  73.   currentBounds.kernelDataSize   = (unsigned int)
  74.     (((Address)(vmMemEnd)) - ((Address)(&end)));
  75.   currentBounds.kernelStacksStart = (unsigned int)vmStackBaseAddr;
  76.   currentBounds.kernelStacksSize = (unsigned int)
  77.     (vmStackEndAddr - vmStackBaseAddr);
  78.   currentBounds.fileCacheStart   = (unsigned int)vmBlockCacheBaseAddr;
  79.   currentBounds.fileCacheSize    = (unsigned int) (vmBlockCacheEndAddr -
  80.                         vmBlockCacheBaseAddr);
  81.   kernelAddress = readPtr->offset;
  82.   bytesLeft = readPtr->length;
  83.   bufPtr = readPtr->buffer;
  84.   if (kernelAddress < sizeof(StopInfo)) {
  85.     if (bytesLeft + kernelAddress <= sizeof(StopInfo)) {
  86.       bcopy(((char *)&stopInfo) + kernelAddress, readPtr->buffer, readPtr->length);
  87.       replyPtr->length = readPtr->length;
  88.       return(SUCCESS);
  89.     }
  90.     bcopy(((char *)&stopInfo) + kernelAddress, readPtr->buffer, sizeof(StopInfo) - kernelAddress);
  91.     bytesLeft -= sizeof(StopInfo) - kernelAddress;
  92.     bufPtr += sizeof(StopInfo) - kernelAddress;
  93.     kernelAddress = sizeof(StopInfo);
  94.   }
  95.   if (kernelAddress < (sizeof(StopInfo) + sizeof(Dbg_DumpBounds))) {
  96.     if (bytesLeft + kernelAddress <= sizeof(StopInfo) + sizeof(Dbg_DumpBounds)) {
  97.       bcopy(((char *)¤tBounds) + sizeof(StopInfo) - kernelAddress, bufPtr, bytesLeft);
  98.       replyPtr->length = readPtr->length;
  99.       return(SUCCESS);
  100.     }
  101.     bcopy(((char *)¤tBounds) + sizeof(StopInfo) - kernelAddress, bufPtr, sizeof(Dbg_DumpBounds));
  102.     bytesLeft -= sizeof(StopInfo) + sizeof(Dbg_DumpBounds) - kernelAddress;
  103.     bufPtr += sizeof(StopInfo) + sizeof(Dbg_DumpBounds) - kernelAddress;
  104.     kernelAddress = mach_KernStart;
  105.   }
  106.   kernelAddress += mach_KernStart - (sizeof(StopInfo) + sizeof(Dbg_DumpBounds));
  107. /*  if (kernelAddress > (Address)(&end) &&
  108.       kernelAddress < VMMACH_VIRT_CACHED_START) {
  109.     return(SYS_INVALID_ARG);
  110.   }*/
  111. #ifdef NOGAP
  112.   if (kernelAddress > vmMemEnd) {
  113.     kernelAddress += vmStackBaseAddr - vmMemEnd;
  114.   }
  115.   if (kernelAddress > vmStackEndAddr) {
  116.     kernelAddress += vmBlockCacheBaseAddr - vmStackEndAddr;
  117.   }
  118.   if (kernelAddress > vmBlockCacheEndAddr) {
  119.     return (SYS_INVALID_ARG);
  120.   }
  121. #else
  122.   if (kernelAddress > vmMemEnd &&
  123.       kernelAddress < vmStackBaseAddr) {
  124.     return(SYS_INVALID_ARG);
  125.   }
  126.   if (kernelAddress > vmStackEndAddr &&
  127.       kernelAddress < vmBlockCacheBaseAddr) {
  128.     return(SYS_INVALID_ARG);
  129.   }
  130.   if (kernelAddress > vmBlockCacheEndAddr) {
  131.     return(SYS_INVALID_ARG);
  132.   }
  133. #endif
  134.   numPages = ((kernelAddress + bytesLeft - 1) >> VMMACH_PAGE_SHIFT) - 
  135.     (kernelAddress >> VMMACH_PAGE_SHIFT);
  136.   if (!Dbg_InRange(kernelAddress, bytesLeft, FALSE)) {
  137.     replyPtr->length = 0;
  138.     return(SYS_ARG_NOACCESS);
  139.   }
  140.   bytesInPage = vm_PageSize - (kernelAddress & (vm_PageSize-1));
  141.   if (bytesLeft < bytesInPage) {
  142.     bcopy(kernelAddress, bufPtr, bytesLeft);
  143.     replyPtr->length = readPtr->length;
  144.     return(SUCCESS);
  145.   }
  146.   bcopy(kernelAddress, bufPtr, bytesInPage);
  147.   bytesLeft -= bytesInPage;
  148.   bufPtr += vm_PageSize;
  149.   while (numPages > 0) {
  150.     if (!Dbg_InRange(kernelAddress, bytesLeft, FALSE)) {
  151.       replyPtr->length = 0;
  152.       return(SYS_ARG_NOACCESS);
  153.     }
  154.     if (bytesLeft < vm_PageSize) {
  155.       bcopy(kernelAddress, bufPtr, bytesLeft);
  156.       replyPtr->length = readPtr->length;
  157.       return(SUCCESS);
  158.     }
  159.     bcopy(kernelAddress, bufPtr, vm_PageSize);
  160.     bytesLeft -= vm_PageSize;
  161.     bufPtr += vm_PageSize;
  162.     numPages--;
  163.   }
  164.   replyPtr->length = readPtr->length;
  165.   return(SUCCESS);
  166. }
  167.  
  168.  
  169. /*
  170.  *----------------------------------------------------------------------
  171.  *
  172.  *  Dev_SmemWrite --
  173.  *
  174.  *    Writes if it can, and returns SUCCESS if it wrote.
  175.  *
  176.  * Results:
  177.  *    A standard Sprite return status.
  178.  *
  179.  * Side effects:
  180.  *    None.
  181.  *
  182.  *----------------------------------------------------------------------
  183.  */
  184. /*ARGSUSED*/
  185. ReturnStatus
  186. Dev_SmemWrite(devicePtr, writePtr, replyPtr)
  187.     Fs_Device *devicePtr;
  188.     Fs_IOParam    *writePtr;    /* Write parameter block */
  189.     Fs_IOReply    *replyPtr;    /* Return length and signal */ 
  190. {
  191.   int bytesLeft;
  192.   int kernelAddress;
  193.   int numPages, bytesInPage;
  194.   char *bufPtr;
  195.   StopInfo stopInfo;
  196.   Dbg_DumpBounds currentBounds;
  197.   
  198.   stopInfo.codeStart = (int)mach_CodeStart;
  199.   stopInfo.trapType = 0;
  200. /*  stopInfo.regs = ;*/
  201.   currentBounds.pageSize = vm_PageSize;
  202.   currentBounds.stackSize = mach_KernStackSize;
  203.   currentBounds.kernelCodeStart = (unsigned int) mach_KernStart;
  204.   currentBounds.kernelCodeSize  =
  205.     (unsigned int) (((Address)(&end)) - mach_KernStart);
  206.   currentBounds.kernelDataStart  = ((unsigned int)(&end));
  207.   currentBounds.kernelDataSize   = (unsigned int)
  208.     (((Address)(vmMemEnd)) - ((Address)(&end)));
  209.   currentBounds.kernelStacksStart = (unsigned int)vmStackBaseAddr;
  210.   currentBounds.kernelStacksSize = (unsigned int)
  211.     (vmStackEndAddr - vmStackBaseAddr);
  212.   currentBounds.fileCacheStart   = (unsigned int)vmBlockCacheBaseAddr;
  213.   currentBounds.fileCacheSize    = (unsigned int) (vmBlockCacheEndAddr -
  214.                         vmBlockCacheBaseAddr);
  215.   kernelAddress = writePtr->offset;
  216.   bytesLeft = writePtr->length;
  217.   bufPtr = writePtr->buffer;
  218.   if (kernelAddress < sizeof(StopInfo)) {
  219.     if (bytesLeft + kernelAddress <= sizeof(StopInfo)) {
  220.       bcopy(writePtr->buffer, ((char *)&stopInfo) + kernelAddress, writePtr->length);
  221.       replyPtr->length = writePtr->length;
  222.       return(SUCCESS);
  223.     }
  224.     bcopy(writePtr->buffer, ((char *)&stopInfo) + kernelAddress, sizeof(StopInfo) - kernelAddress);
  225.     bytesLeft -= sizeof(StopInfo) - kernelAddress;
  226.     bufPtr += sizeof(StopInfo) - kernelAddress;
  227.     kernelAddress = sizeof(StopInfo);
  228.   }
  229.   if (kernelAddress < (sizeof(StopInfo) + sizeof(Dbg_DumpBounds))) {
  230.     if (bytesLeft + kernelAddress <= sizeof(StopInfo) + sizeof(Dbg_DumpBounds)) {
  231.       bcopy(bufPtr, ((char *)¤tBounds) + sizeof(StopInfo) - kernelAddress, bytesLeft);
  232.       replyPtr->length = writePtr->length;
  233.       return(SUCCESS);
  234.     }
  235.     bcopy(bufPtr, ((char *)¤tBounds) + sizeof(StopInfo) - kernelAddress, sizeof(Dbg_DumpBounds));
  236.     bytesLeft -= sizeof(StopInfo) + sizeof(Dbg_DumpBounds) - kernelAddress;
  237.     bufPtr += sizeof(StopInfo) + sizeof(Dbg_DumpBounds) - kernelAddress;
  238.     kernelAddress = mach_KernStart;
  239.   }
  240.   kernelAddress += mach_KernStart - (sizeof(StopInfo) + sizeof(Dbg_DumpBounds));
  241.  
  242. #ifdef NOGAP
  243.   if (kernelAddress > vmMemEnd) {
  244.     kernelAddress += vmStackBaseAddr - vmMemEnd;
  245.   }
  246.   if (kernelAddress > vmStackEndAddr) {
  247.     kernelAddress += vmBlockCacheBaseAddr - vmStackEndAddr;
  248.   }
  249.   if (kernelAddress > vmBlockCacheEndAddr) {
  250.     return (SYS_INVALID_ARG);
  251.   }
  252. #else
  253.   if (kernelAddress > vmMemEnd &&
  254.       kernelAddress < vmStackBaseAddr) {
  255.     return(SYS_INVALID_ARG);
  256.   }
  257.   if (kernelAddress > vmStackEndAddr &&
  258.       kernelAddress < vmBlockCacheBaseAddr) {
  259.     return(SYS_INVALID_ARG);
  260.   }
  261.   if (kernelAddress > vmBlockCacheEndAddr) {
  262.     return(SYS_INVALID_ARG);
  263.   }
  264. #endif
  265.  
  266.   numPages = ((kernelAddress + bytesLeft - 1) >> VMMACH_PAGE_SHIFT) - 
  267.     (kernelAddress >> VMMACH_PAGE_SHIFT);
  268.   if (!Dbg_InRange(kernelAddress, bytesLeft, FALSE)) {
  269.     replyPtr->length = 0;
  270.     return(SYS_ARG_NOACCESS);
  271.   }
  272.   bytesInPage = vm_PageSize - (kernelAddress & (vm_PageSize-1));
  273.   if (bytesLeft < bytesInPage) {
  274.     bcopy(bufPtr, kernelAddress, bytesLeft);
  275.     replyPtr->length = writePtr->length;
  276.     return(SUCCESS);
  277.   }
  278.   bcopy(bufPtr, kernelAddress, bytesInPage);
  279.   bytesLeft -= bytesInPage;
  280.   bufPtr += vm_PageSize;
  281.   while (numPages > 0) {
  282.     if (!Dbg_InRange(kernelAddress, bytesLeft, FALSE)) {
  283.       replyPtr->length = 0;
  284.       return(SYS_ARG_NOACCESS);
  285.     }
  286.     if (bytesLeft < vm_PageSize) {
  287.       bcopy(bufPtr, kernelAddress, bytesLeft);
  288.       replyPtr->length = writePtr->length;
  289.       return(SUCCESS);
  290.     }
  291.     bcopy(bufPtr, kernelAddress, vm_PageSize);
  292.     bytesLeft -= vm_PageSize;
  293.     bufPtr += vm_PageSize;
  294.     numPages--;
  295.   }
  296.   replyPtr->length = writePtr->length;
  297.   return(SUCCESS);
  298. }
  299.  
  300.  
  301. /*
  302.  *----------------------------------------------------------------------
  303.  *
  304.  * Dev_SmemIOControl --
  305.  *
  306.  *    This procedure handles IOControls for /dev/smem and other
  307.  *    devices.  It refuses all IOControls except for a few of
  308.  *    the generic ones, for which it does nothing.
  309.  *
  310.  * Results:
  311.  *    A standard Sprite return status.
  312.  *
  313.  * Side effects:
  314.  *    None.
  315.  *
  316.  *----------------------------------------------------------------------
  317.  */
  318.  
  319. /* ARGSUSED */
  320. ReturnStatus
  321. Dev_SmemIOControl(devicePtr, ioctlPtr, replyPtr)
  322.     Fs_Device            *devicePtr;
  323.     Fs_IOCParam        *ioctlPtr;
  324.     Fs_IOReply        *replyPtr;
  325. {
  326.     if ((ioctlPtr->command == IOC_GET_FLAGS)
  327.     || (ioctlPtr->command == IOC_SET_FLAGS)
  328.     || (ioctlPtr->command == IOC_SET_BITS)
  329.     || (ioctlPtr->command == IOC_CLEAR_BITS)
  330.     || (ioctlPtr->command == IOC_REPOSITION)) {
  331.     return SUCCESS;
  332.     }
  333.     return GEN_NOT_IMPLEMENTED;
  334. }
  335.  
  336. /*
  337.  *----------------------------------------------------------------------
  338.  *
  339.  * Dev_SmemSelect --
  340.  *
  341.  *    This procedure handles selects for /dev/smem and other
  342.  *    devices that are always ready.
  343.  *
  344.  * Results:
  345.  *    The device is indicated to be readable and writable.
  346.  *
  347.  * Side effects:
  348.  *    None.
  349.  *
  350.  *----------------------------------------------------------------------
  351.  */
  352.  
  353. /* ARGSUSED */
  354. ReturnStatus
  355. Dev_SmemSelect(devicePtr, readPtr, writePtr, exceptPtr)
  356.     Fs_Device    *devicePtr;    /* Ignored. */
  357.     int    *readPtr;        /* Read bit to clear if not readable */
  358.     int    *writePtr;        /* Write bit to clear if not readable */
  359.     int    *exceptPtr;        /* Except bit to clear if not readable */
  360. {
  361.     *exceptPtr = 0;
  362.     return(SUCCESS);
  363. }
  364.